Skip to main content

Overview

This page provides common SQL query patterns for analyzing Steam Market data across all tables. All examples use the item "AK-47 | Redline (Field-Tested)" - replace with your tracked items.

Connecting to the Database

sqlite3 data/market_data.db
All timestamps are stored in UTC. Remember to adjust for your local timezone when interpreting results.

Basic Queries

Get the most recent price snapshot for an item:
SELECT timestamp, lowest_price, median_price, volume
FROM price_overview
WHERE market_hash_name = 'AK-47 | Redline (Field-Tested)'
ORDER BY timestamp DESC
LIMIT 1;

Historical Analysis

Calculate daily average price over the last 30 days:
SELECT date(time) AS day,
       AVG(price) AS avg_price,
       SUM(volume) AS total_volume
FROM price_history
WHERE market_hash_name = 'AK-47 | Redline (Field-Tested)'
  AND time > datetime('now', '-30 days')
GROUP BY date(time)
ORDER BY day DESC;

Order Book Analysis

Get full order book (latest snapshot):
SELECT timestamp, buy_order_table, sell_order_table
FROM orders_histogram
WHERE market_hash_name = 'AK-47 | Redline (Field-Tested)'
ORDER BY timestamp DESC
LIMIT 1;

Activity Analysis

Track activity volume over time:
SELECT 
    strftime('%Y-%m-%d %H:00', timestamp) AS hour,
    SUM(activity_count) AS total_activities,
    COUNT(*) AS snapshots_captured
FROM orders_activity
WHERE market_hash_name = 'AK-47 | Redline (Field-Tested)'
  AND timestamp > datetime('now', '-24 hours')
GROUP BY strftime('%Y-%m-%d %H:00', timestamp)
ORDER BY hour DESC;

Cross-Item Comparisons

Compare current prices across all tracked items:
SELECT market_hash_name,
       MAX(timestamp) AS last_update,
       lowest_price,
       volume
FROM price_overview
GROUP BY market_hash_name
ORDER BY volume DESC;

Advanced Queries

7-day simple moving average:
SELECT 
    time,
    price,
    AVG(price) OVER (
        ORDER BY time
        ROWS BETWEEN 167 PRECEDING AND CURRENT ROW
    ) AS sma_7day
FROM price_history
WHERE market_hash_name = 'AK-47 | Redline (Field-Tested)'
  AND time > datetime('now', '-30 days')
ORDER BY time DESC;
168 hours = 7 days × 24 hours (7-day moving average)

JSON Manipulation

Extract all buy orders as individual rows:
SELECT 
    timestamp,
    json_each.key AS order_index,
    json_each.value ->> '$.price' AS price,
    json_each.value ->> '$.quantity' AS quantity
FROM orders_histogram,
     json_each(buy_order_table)
WHERE market_hash_name = 'AK-47 | Redline (Field-Tested)'
  AND id = (SELECT MAX(id) FROM orders_histogram 
            WHERE market_hash_name = 'AK-47 | Redline (Field-Tested)')
ORDER BY price DESC;

Export & Backup

Export to CSV

# Export all price history
sqlite3 -header -csv data/market_data.db \
  "SELECT * FROM price_history" > price_history.csv

# Export specific item
sqlite3 -header -csv data/market_data.db \
  "SELECT * FROM price_history WHERE market_hash_name = 'AK-47 | Redline (Field-Tested)'" \
  > ak47_redline.csv

Backup Database

# Create backup
sqlite3 data/market_data.db ".backup data/market_data_backup.db"

# Restore from backup
sqlite3 data/market_data.db ".restore data/market_data_backup.db"

Performance Tips

Check if your queries are using indexes efficiently:
EXPLAIN QUERY PLAN
SELECT * FROM price_overview 
WHERE market_hash_name = 'AK-47 | Redline (Field-Tested)'
ORDER BY timestamp DESC
LIMIT 1;
Look for “USING INDEX” in the output.
Always use LIMIT when you don’t need all rows:
-- Good: Only fetch what you need
SELECT * FROM price_history LIMIT 100;

-- Bad: Fetches everything (can be millions of rows)
SELECT * FROM price_history;
Apply WHERE clauses before JOINs and aggregations:
-- Good: Filter first
SELECT AVG(price)
FROM price_history
WHERE market_hash_name = 'AK-47 | Redline (Field-Tested)'
  AND time > datetime('now', '-7 days');

-- Bad: Scans entire table
SELECT AVG(price)
FROM price_history
WHERE time > datetime('now', '-7 days');
When extracting JSON data, cast to appropriate types:
-- Cast to numeric for calculations
CAST(json_extract(buy_order_table, '$[0].price') AS REAL)

-- Cast to integer for counts
CAST(json_extract(buy_order_table, '$[0].quantity') AS INTEGER)

Database Overview

Learn about the database architecture

price_overview

Current market prices table

orders_histogram

Order book data table

price_history

Historical price data table